#include <stdio.h>
#include "xfat.h"
#include "xdisk.h"

xfat_err_t xdisk_hw_open(xdisk_t *disk, void *init_data)
{
    const char *path = (const char *)init_data;
    FILE *file = fopen(path, "rb+"); //以读写方式打开文件
    if (file == NULL)
    {
        printf("open vdisk failed!\n");
        return FS_ERR_IO;
    }
    disk->data = file;
    disk->sector_size = 512;
    fseek(file, 0, SEEK_END); //文件指针定位到文件末尾
    disk->total_sector = ftell(file) / disk->sector_size;
    return FS_ERR_OK;
}

xfat_err_t xdisk_hw_close(xdisk_t *disk)
{
    FILE *file = (FILE *)disk->data;
    fclose(file);
    return FS_ERR_OK;
}

xfat_err_t xdisk_hw_read_sector(xdisk_t *disk, uint8_t *buffer, uint32_t start_sector, uint32_t sector_count)
{
    uint32_t offset = start_sector * disk->sector_size;
    FILE *file = (FILE *)disk->data;
    int err = fseek(file, offset, SEEK_SET);//从文件开头偏移到需要read的位置
    if (err == -1)
    {
        printf("seek file failed! file:0x%x\n", offset);
        return FS_ERR_IO;
    }
    err = fread(buffer, disk->sector_size, sector_count, file);
    if (err == -1)
    {
        printf("read vdisk failed! sector:%d, count:%d\n", start_sector, sector_count);
        return FS_ERR_IO;
    }
    return FS_ERR_OK;
}

xfat_err_t xdisk_hw_write_sector(xdisk_t *disk, uint8_t *buffer, uint32_t start_sector, uint32_t sector_count)
{
    uint32_t offset = start_sector * disk->sector_size;
    FILE *file = (FILE *)disk->data;
    int err = fseek(file, offset, SEEK_SET);//从文件开头偏移到需要write的位置
    if (err == -1)
    {
        printf("seek file failed! file:0x%x\n", offset);
        return FS_ERR_IO;
    }
    err = fwrite(buffer, disk->sector_size, sector_count, file);
    if (err == -1)
    {
        printf("write vdisk failed! sector:%d, count:%d\n", start_sector, sector_count);
        return FS_ERR_IO;
    }

    fflush(file);
    return FS_ERR_OK;
}

//虚拟设备实例化
xdisk_driver_t vdisk_driver = {
    .open = xdisk_hw_open,
    .close = xdisk_hw_close,
    .read_sector = xdisk_hw_read_sector,
    .write_sector = xdisk_hw_write_sector};